package org.lynn.lambda.test;

import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;

/**
 * @author linzou@linkdoc.com
 * @ClassName: JCFMapWithLambda
 * @Description:
 * @date 2019/6/27 2:00 PM
 */
public class JCFMapWithLambda {

    HashMap<Integer, String> map = new HashMap<>();

    @Before
    public void initElement() {

        map.put(1, "one");
        map.put(2, "two");
        map.put(3, "three");

    }

    @Test
    public void foreachMapWithJava7() {
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }
    }

    @Test
    public void foreachMapWithAnonymousClass() {
        map.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer integer, String s) {
                System.out.println(integer + "=" + s);
            }
        });
    }

    @Test
    public void foreachMapWithLambda() {
        map.forEach((k, v) -> System.out.println(k + "=" + v));
    }

    @Test
    public void getOrDefaultWithJava7() {
        if (map.containsKey(4)) {
            System.out.println(map.get(4));
        } else {
            System.out.println("NoValue");
        }
    }

    @Test
    public void getOrDefaultWithLambda() {
        System.out.println(map.getOrDefault(4, "NoValue"));
    }

    @Test
    public void putIfAbsent() {
        map.putIfAbsent(4, "four");
        System.out.println(map.getOrDefault(4, "NoValue"));
    }

    @Test
    public void remove() {
        map.putIfAbsent(4, "four");
        //java8 新增的 remove 方法指定的key和value同时在map中存在时，才移除该元素
        map.remove(4, "five");
        System.out.println(map.getOrDefault(4, "NoValue"));
    }

    @Test
    public void replaceKeyAndValue() {
        map.putIfAbsent(4, "4");
        System.out.println(map.getOrDefault(4, "NoValue"));
        //只有在当前Map中key的映射存在时才用value去替换原来的值，否则什么也不做．
        map.replace(4, "four");
        System.out.println(map.getOrDefault(4, "NoValue"));
    }

    @Test
    public void replaceKeyOldValueNewValue() {
        map.putIfAbsent(4, "4");
        System.out.println(map.getOrDefault(4, "NoValue"));
        map.replace(4, "four", "4");
        System.out.println(map.getOrDefault(4, "NoValue"));
        //只有在当前Map中key的映射存在且等于oldValue时才用newValue去替换原来的值，否则什么也不做．
        map.replace(4, "4", "4-four");
        System.out.println(map.getOrDefault(4, "NoValue"));
    }

    @Test
    public void replaceAllWithJava7() {
        for (Map.Entry<Integer, String> entry : map.entrySet()) {
            entry.setValue(entry.getValue().toUpperCase());
        }

        System.out.println(map);
    }

    @Test
    public void replaceAllWithAnonymousClass() {
        map.replaceAll(new BiFunction<Integer, String, String>() {
            @Override
            public String apply(Integer integer, String s) {
                return s.toUpperCase();
            }
        });
        System.out.println(map);
    }

    @Test
    public void replaceAllWithLambda() {
        map.replaceAll((k, v) -> v.toUpperCase());
        System.out.println(map);
    }


    @Test
    public void merge() {
        Map<String, Integer> map = new HashMap<>();

        map.put("A", 1000);
        map.put("B", 2000);
        map.put("C", 3000);

        // add new key value ("A",99), if key "A" exist in map then do function  "(X,Y) -> (Y+X)" ,the function return value will replace the oldvalue.
        Integer newValue1 = map.merge("A", 99, (X, Y) -> (Y + X));
        Integer newValue2 = map.merge("A", 888, (X, Y) -> Y);
        // add new key value ("D",666), if key "D" not exist in map then insert the key value to map
        Integer newValue3 = map.merge("D", 666, (X, Y) -> Y);
        Integer newValue4 = map.merge(null, 777, (X, Y) -> Y);
        Integer newValue5 = map.merge(null, 5555, (X, Y) -> Y);

        map.forEach((k, v) -> System.out.println(k + "=" + v));
    }


    @Test
    public void compute() {
        map.compute(4, new BiFunction<Integer, String, String>() {
            @Override
            public String apply(Integer integer, String s) {
                System.out.println("t值=" + integer);
                System.out.println("u值=" + s);

                return integer + "_" + s;
            }
        });

        System.out.println(map);
    }

    @Test
    public void computeWithLambda() {
        map.compute(4, (k, v) -> k + "_" + v);
        System.out.println(map);
    }

    @Test
    public void computeIfAbsentWithJava7() {
        Map<Integer, Set<String>> map = new HashMap<>();

        if (map.containsKey(1)) {
            map.get(1).add("one");
        } else {
            Set<String> valueSet = new HashSet<>();
            valueSet.add("one");
            map.put(1, valueSet);
        }

        System.out.println(map);

    }


    @Test
    public void computeIfAbsentWithLambda() {
        Map<Integer, Set<String>> map = new HashMap<>();
        map.computeIfAbsent(1, value -> new HashSet<>()).add("one");
        System.out.println(map);
    }


    @Test
    public void computeIfPresentWithJava7() {

    }





}
